

#pragma once


#include <bits/types/FILE.h>
#include <functional>
#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <cstdio>
#include "define.h"

extern "C"
{
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libavcodec/codec.h>

}

struct DecoderFile 
{
    std::string m_file_name;
    FILE * m_file_handle;
};

struct CallbackData
{
    ProcessFrameFunc m_func;
    void * m_user_data;
};

struct Demuxer
{
    AVFormatContext * format_ctx;
    AVCodecContext  * video_ctx;
    int               video_index;
    AVCodecContext  * audio_ctx;
    int               audio_index;

    CallbackData * video_user_data;
    CallbackData * audio_user_data;
};


class BaseStream 
{
public:
    BaseStream();
    static BaseStream * CreateMediaStreamByMediaType(int type);
public:
    virtual const AVCodec * AddStream(AVFormatContext * format_ctx, const std::string & codec_name) = 0;
};

class VideoStream : public BaseStream
{
public:
    VideoStream();
    virtual const AVCodec * AddStream(AVFormatContext * format_ctx, const std::string & codec_name) override;
};

class AudioStream : public BaseStream
{
public:
    AudioStream();
    virtual const AVCodec * AddStream(AVFormatContext * format_ctx, const std::string & codec_name) override;
};

void ProcessFile(const std::string & input_file);
void ProcessMuxer(const std::string & input_file);

